/*
 *	MIDAS Context Based Routing
 *	cbr_acache.h
 *	Copyright (c) 2007 Bartlomiej Zolnierkiewicz
 *	MEAG IT PW
 */

#ifndef _cbr_acache_h
#define _cbr_acache_h

#include "cbr_types.h"

//#include <netinet/in.h>
#include <net/ethernet.h> // for struct ether_addr

#include <list>

class CBR;

typedef u_int32_t ip_addr;

typedef struct ether_addr mac_addr;

class cbr_IPMapping {
private:
	cbr_ID		id_;	// node ID
	ip_addr		ip_;	// IP address

public:
	cbr_IPMapping(cbr_ID id, ip_addr ip)
	{
		id_ = id;
		ip_ = ip;
	}

	cbr_ID		getID() const { return id_; }
	ip_addr		getIP() const { return ip_; }
};

class cbr_MACMapping {
private:
	cbr_ID		id_;	// node ID
	mac_addr	mac_;	// MAC address

public:
	cbr_MACMapping(cbr_ID id, mac_addr mac)
	{
		id_  = id;
		mac_ = mac;
	}

	cbr_ID		getID() const { return id_; }
	mac_addr	getMAC() const { return mac_; }
};

class cbr_IPCache {
private:
	typedef std::list<cbr_IPMapping *> mappings_list;
	mappings_list mappings;

public:
	// depends on CBR->localID so must be called _after_ constructor
	void			init(CBR *);

	void			insert(cbr_ID id, ip_addr ip);
	const ip_addr		lookup(cbr_ID id) const;

	void			purge(void);
};

class cbr_MACCache {
private:
	typedef std::list<cbr_MACMapping *> mappings_list;
	mappings_list mappings;

public:
	// depends on CBR->localID so must be called _after_ constructor
	void			init(CBR *);

	void			insert(cbr_ID id, mac_addr mac);
	const mac_addr		lookup(cbr_ID id) const;

	void			purge(void);
};

static inline char * mactostr(mac_addr *mac)
{
	static char tmp[18];
	char *s = &tmp[0];

	for (int i = 0; i < 6; i++)
		s += sprintf(s, "%02x%s", mac->ether_addr_octet[i],
			     (i != 5) ? ":" : "\0");

	return &tmp[0];
}

// for inet_ntoa()
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

static inline char * iptostr(ip_addr *ip)
{
	struct in_addr in;
	in.s_addr = *ip;

	return inet_ntoa(in);
}

#endif
